/*
 *  myangio.h
 *  fix
 *
 *  Created by wumin on 8/2/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */



#include "../Matrix.h"


class VesselCell{
public:
 int coverlimit;
 int cIndex;
 double i[15];//coverlimit
 double j[15];//coverlimit
 int cConnectRange;
 int cConnection;
 int cCover;
 
 char cFate;//'S'=Stable,'T'=Sprout Tip, 'D'= Die and Silent, 'P'=Stalk cell which proliferate
 double cReceptor;
 double cRadius;
 double cPermeability;
 double cPericytes;
 
 bool cSetPressure;
 int cConnectIndex[32];//cConnectRange
//Matrix cConnectIndex;

 VesselCell* pNextVesselCell;
 VesselCell* pPreviousVesselCell;
VesselCell();
~VesselCell();
};




class CellVesselStructure{
private:



public:


void InitializeCellTime(bool Resume);
void InitializeCellList(bool VesselResume);
//bool SaveVesselList(void);//not modi
//void GenerateMatrix(void);//not modi
void ShuffleFate(Matrix& Signal);
void MemoShuffleFate(Matrix& Signal);
void ColorCell(void);
CellVesselStructure* GetAddress(void);

//void String_Interact(Matrix& Signal);
//void Grow(Matrix& Signal);
//void GrowSprout(Matrix& Signal);
//void Grow_zero(Matrix& Signal);
//void Grow_One(Matrix& Signal);
//void Grow_Deprecate(Matrix& Signal);
VesselCell* FindCell(int Index);
VesselCell* FindCell(int i, int j);
void SetSprout(Matrix& Signal);
void MemoSetSprout(Matrix& Signal);
int CellListLength;
int SproutNumber;

Matrix Distance;
Matrix pRadius;
Matrix pPermeability;
Matrix pConduct;
Matrix pFlow;
Matrix pPericytes;
//double Indicator[201][201];//Xnodes Ynodes


VesselCell* pFirstVesselCell;
VesselCell* pLastVesselCell;




//void PutArteryandSprout();
CellVesselStructure();
~CellVesselStructure();
};

bool Connected(VesselCell* a, VesselCell* b);
void Connect(VesselCell* a, VesselCell* b);
void DisConnect(VesselCell* a, VesselCell* b);
void RemoveUnConnectedPoint(VesselCell* a, int i, int j);
//bool TestConnect(VesselCell* a, VesselCell* b);
void CompeteFate(VesselCell* a, VesselCell* b, Matrix& Signal, char Win, char Lose, char Fair);
void MemoCompeteFate(VesselCell* a, VesselCell* b, Matrix& Signal, char Win, char Lose, char Fair);
void SetTipFate(VesselCell* a, Matrix& Signal, char Win, char Lose, double Threshold);
void MemoSetTipFate(VesselCell* a, Matrix& Signal, char Win, char Lose, double Threshold);
void SetTipFate(VesselCell* a, Matrix& Signal, char Win, char Lose);


int min_Round(double input);
 double min_prob(double a, int b, int N);

/************************hualidefeigexian********************/

double AngioSORUpdate( Matrix& Solution, Matrix& ConductX, Matrix& ConductY, Matrix& BloodVesselIndicatorX, Matrix& BloodVesselIndicatorY, int i, int j, double MaxConduct);
class VesselPoint{
public:
 int i;
 int j;
 bool AmIArtery;
 bool AmIVenous;
 double MyAge;
 int i_origin;
 int j_origin;
VesselPoint* pNextVesselPoint;
VesselPoint* pPreviousVesselPoint;
VesselPoint();
~VesselPoint();

};

class VesselStructure{
private:

void InitializeTime(bool Resume);
void InitializeVesselMatrix(bool VesselResume);
void InitializeVesselListInOrder(bool VesselResume);
void InjectPosition(int innumbers, int outnumbers, bool randomized);



void GrowSprout(void);
void GrowSprout(Matrix& Shuffle);
void GrowSprout_one_step(void);
void CleanUp(Matrix& Shuffle);
void GrowSprout(CellVesselStructure* TheVessel);
void Remove(CellVesselStructure* TheVessel);
void Retract(CellVesselStructure* TheVessel);
void GrowSprout_onecell(CellVesselStructure* TheVessel);
void GrowSprout_Step(CellVesselStructure* TheVessel,int Step);
void WSSTAFBranchByProbInterval(Matrix& Shuffle);

void VesselAdaption(void);
void UpdateHematocrit(void);
void MindeUpdateHematocrit(void);

void UpdateViscosity(void);
void UpdateWallShearStress(void);
void OutPutStudy(void);
void OutPutStudy_Area(void);
void UpdateTracer_P(double Pa, double Pb, double Pd, Matrix& Paolo, Matrix& PaoloS);
void UpdateRadius(void);
void UpdateRadius_Cell(void);
void UpdateRadius_Flow(void);
void UpdateConductivity(void);
void Proliferate(void);
void CellDiffuse(void);

void GetVesselPressureAndFlow(double Tolerance);



public:
VesselPoint* pFirstVesselPoint;
VesselPoint* pLastVesselPoint;
double NodeLength;
int SproutNumber;
int CellNumber;
int VesselListLength;
void ArteryPosition(void);
void VesselInitialization( bool VesselResume, CellVesselStructure* TheVessel );
void UpdateVesselSystemSteadyStateShuffle(CellVesselStructure* TheVessel);
void ChainAngioPressureUpdate(int MaxIterations, double Tolerance);
void InterAngioPressureUpdate(int MaxIterations, double Tolerance);

double PTUpdate(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable,int i,int j);
double Transport_P(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable,int i,int j,double dt);
double Transport_DI(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable, Matrix& VariableS, Matrix& Fraction, int i,int j,double dt);
double Injection_P(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable,int i,int j,double number);
double Injection_DI(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable, Matrix& Fraction, int i,int j,double number);
double Accumulate(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable,int i,int j,double dt);
double Accumulate_D(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable, Matrix& VariableS,int i,int j,double dt);
double PTUpdate_Wave(Matrix& CoeffecientX, Matrix& CoeffecientY, Matrix& Variable,int i,int j);
void Adhere(void);
void TransOutPut(void);
void TransOutPutThresholdFlow(void);
void UpdateVEGFR(void);
void UpdateNotch(void);
void UpdateDelta4(void);
void UpdatePermeability(void);
void RegenerateFlow(void);

void GetRadiusValue(void);
void SteadyStateHematocrit(void);
void Transportation_P(void);
void Transportation_DI(double t);
bool SaveVesselList(void);
void MakeList(void);
void Remodel(CellVesselStructure* TheVessel);
void InitialGrowSprout(CellVesselStructure* TheVessel);
bool UpdateOxyVWTPressure( void );
void WithOxygenVWTGhostFluidMethod_Generic_MatrixForm(Matrix& X, Matrix& Y, Matrix& Phi, 
													 Matrix& Diffusivity, 
													 Matrix& SourceFunction, Matrix& SourceFunctionU, 
													 double (*PLeftBC)(double),   char PLeftBCtype,  
													 double (*PRightBC)(double),  char PRightBCtype,     
													 double (*PBottomBC)(double), char PBottomBCtype,   
													 double (*PTopBC)(double),    char PTopBCtype,  
													 double (*JumpCondition)(double,double), 
													 double (*NormalJumpCondition)(double,double), double PTolerance,
													 /* Matrix& InitialGuess, */ 
													 double (*LeftBC)(double),   char LeftBCtype,  
													 double (*RightBC)(double),  char RightBCtype,     
													 double (*BottomBC)(double), char BottomBCtype,   
													 double (*TopBC)(double),    char TopBCtype,  
													 double (*DiffusionConstant)(double,double,double,int,int), 
													 double (*SourceTimesU)(double,double,double,int,int),
													 double (*SourceRemainder)(double,double,double,int,int),
													 int MaxIterations, double OTolerance ,
													 double ImplicitUpdate(
																		   Matrix& Solution, 
																		   double (*Diffusion)(double,double,double,int,int),
																		   double (*SourceTimesU)(double,double,double,int,int),
																		   double (*SourceRemainder)(double,double,double,int,int), 
																		   int i, int j, 
																		   double x, double y, double dx, double dy ),
	/*
	 double UpdateBoundaryPoint( Matrix& Solution, 
	 double (*LeftBC)(double),   char LeftBCtype,  
	 double (*RightBC)(double),  char RightBCtype,     
	 double (*BottomBC)(double), char BottomBCtype,   
	 double (*TopBC)(double),    char TopBCtype,  
	 int i, int j, 
	 double x, double y )*/
													 double UpdateBoundaryPoint(Matrix& Solution, 
																				double (*Diffusion)(double,double,double,int,int),
																				double (*SourceTimesU)(double,double,double,int,int),
																				double (*SourceRemainder)(double,double,double,int,int), 
																				int i, int j, 
																				double x, double y, double dx, double dy),double WTolerance,
													 double AngioFluidPressureUpdate( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Pressure, Matrix& Solution, Matrix& CellSource,  int i, int j),
													 double FluidPressureUpdateBoundaryPoint( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Pressure, Matrix& Solution,   int i, int j), double VTolerance
													 
													  );
	
//void PutArteryandSprout();
VesselStructure();
~VesselStructure();
};

double Prob_Proliferate(int i, int j, double k_v_proliferate, double k_n_d_proliferate);
double Prob_Differentiate(int i, int j, double k_n_d_transit, double min_n);
double Prob_Transit(int i, int j, double k_v_transit, double k_n_d_transit);
void AngioUpdateMDE(void);
void AngioUpdateECM(void);
void AngioUpdateTAF(void);
void UpdateStability(void);
void MoveMCell(double Time, double Duration);
void GetMaxTAF(void);
void GetMaxTracer(void);
double min_abs(double);
double FluidPressureUpdateBoundaryPoint( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Solution,   int i, int j);
double FluidPressureUpdateBoundaryPoint( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Pressure, Matrix& Solution,   int i, int j);

double FluidPressureUpdateBoundaryPointD( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Solution,   int i, int j);
double AngioFluidPressureUpdate( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Solution,   int i, int j);
double AngioFluidPressureUpdate( Matrix& Diffusion,  Matrix& BloodNodePressure, Matrix& Pressure, Matrix& Solution, Matrix& CellSource,  int i, int j);
double AngioLymSORUpdate( Matrix& Permeability, Matrix& InterPressure, Matrix& Solution, Matrix& ConductX, Matrix& ConductY, Matrix& BloodVesselIndicatorX, Matrix& BloodVesselIndicatorY,  int i, int j, double MaxConduct);
double ImplicitConvectUpdate(
							 Matrix& Diffusion, Matrix& Source, Matrix& PreviousTimeStep, Matrix& Solution,
							 double (*SourceTimesU)(double,int,int), int i, int j);
double ImplicitConvectUpdateBoundaryPoint(
										  Matrix& Diffusion, Matrix& Source, Matrix& PreviousTimeStep, 
										  double (*SourceTimesU)(double,int,int), int i, int j);

